# coding:utf-8
import re
from . import api
from flask import request, jsonify, current_app, session
from ihome.utils.response_code import RET
from ihome import redis_store, db, constants
from ihome.models import User


@api.route('/user', methods=['POST'])
def register():
    """用户注册"""
    # 接受参数，手机号，短信验证码，密码，json格式的数据
    request_data = request.get_json()
    mobile = request_data.get('mobile')
    sms_code = request_data.get('sms_code')
    password = request_data.get('password')

    # 校验参数
    if not all([mobile, sms_code, password]):
        response = {
            'errno': RET.PARAMERR,
            'errmsg': '缺失参数'
        }
        return jsonify(response)
    # 判断手机号格式
    if not re.match(r'1[34578]\d{9}', mobile):
        response = {
            'errno': RET.DATAERR,
            'errmsg': '缺失参数'
        }
        return jsonify(response)
    # 判断短信验证码
    try:
        real_sms_code = redis_store.get('sms_code_%s' % mobile)
        if real_sms_code != sms_code:
            raise ValueError('短信验证码有误或已过期')
        # 校验后删除验证码
        redis_store.delete('sms_code_%s' % mobile)
    except Exception as e:
        resp = {
            "errno": RET.DATAERR,
            "errmsg": '短信验证码有误或已过期'
        }
        return jsonify(resp)
    # 保存用户的数据到数据库中
    user = User(name=mobile, mobile=mobile)
    # 对password属性的设置，会调用属性方法，进行加密操作
    user.password = password
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        # 表示该手机号已经被注册过了
        response = {
            'errno': RET.DATAEXIST,
            'errmsg': '该手机号已经被注册'
        }
        return jsonify(response)
    # 保持用户登录状态
    session['uid'] = user.id
    session['username'] = mobile
    session['mobile'] = mobile

    # 返回值
    response = {
        "errno": RET.OK,
        "errmsg": "注册成功"
    }
    return jsonify(response)


@api.route('/login', methods=['POST'])
def login():
    recv_data = request.get_json()
    username = recv_data.get('username')
    password = recv_data.get('password')

    if not all([username, password]):
        response = {
            'errno': RET.PARAMERR,
            'errmsg': '缺失参数'
        }
        return jsonify(response)
    # 判断用户的登录失败次数
    user_ip = request.remote_addr
    try:
        login_failed_num = redis_store.get('login_failed_num_%s' % user_ip)
    except Exception as e:
        current_app.logger.error(e)
    else:
        # 如果登录失败次数大于最大数，直接返回
        if login_failed_num is not None and int(login_failed_num) >= constants.LOGIN_FAILED_MAX_NUM:
            return jsonify(errno=RET.REQERR, errmsg='登录过于频繁，请稍后再试')

    # 判断登录方式
    try:
        if re.match(r'1[34578]\d{9}', username):
            user = User.query.filter_by(mobile=username).first()
        else:
            user = User.query.filter_by(name=username).first()
        if user is not None:
            if user.check_password(password):
                # 密码正确
                # 记录用户登录状态
                session['uid'] = user.id
                session['username'] = user.name
                session['mobile'] = user.mobile
                # 清除redis中的登录失败次数
                redis_store.delete('login_failed_num_%s' % user_ip)
                return jsonify(errno=RET.OK, errmsg='登录成功')
            else:
                # 密码错误
                # 记录失败次数
                redis_store.incr('login_failed_num_%s' % user_ip)
                redis_store.expire('login_failed_num_%s' % user_ip, constants.LOGIN_FAILED_FORBID_TIME)
        else:
            # 用户不存在
            return jsonify(errno=RET.DBERR, errmsg='用户名或手机号不存在')
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.LOGINERR, errmsg='登录失败')


@api.route('/logout')
def logout():
    """退出登录"""
    session.clear()
    return jsonify(errno=RET.OK, errmsg='退出登录')


@api.route('/user/check_login')
def check_login():
    """检测用户是否登录"""
    username = session.get('username')
    if username is not None:
        return jsonify(errno=RET.OK, errmsg='已登录', data={'username': username})
    else:
        return jsonify(errno=RET.SESSIONERR, errmsg='未登录')
